#ifndef _UI_H_
#define _UI_H_

#include "graphics.h"

#define EVENT_UNHANDLED	0
#define EVENT_HANDLED	1

#define SML_FONT 15
#define LGE_FONT 20

#define UIMSG_OK 0
#define UIMSG_YN 1
#define UIMSG_OC 2

#define UI_WIDGET_NULL		0x00
#define UI_WIDGET_LABEL		0x01
#define UI_WIDGET_BUTTON	0x02
#define UI_WIDGET_CONTAINER	0x03
#define UI_WIDGET_TEXT		0x04
#define UI_WIDGET_NUM		0x05
#define UI_WIDGET_CHECK		0x06
#define UI_WIDGET_HEADER	0x07
#define UI_WIDGET_CONSOLE	0x08
#define UI_WIDGET_PBAR		0x09
#define UI_WIDGET_TEXTBOX	0x0A
#define UI_WIDGET_HSLIDE	0x0B
#define UI_WIDGET_LIST		0x0C
#define UI_WIDGET_LISTROW	0x0D

struct widget_s;

#ifndef _HAVE_SPRITE_TYPE
#define _HAVE_SPRITE_TYPE
typedef struct sprite_s {
	GLfloat x;
	GLfloat y;
	GLfloat w;
	GLfloat h;
	material_t *mat;
} sprite_t;
#endif

#ifndef _HAVE_MSGBOX_DATA_TYPE
#define _HAVE_MSGBOX_DATA_TYPE
typedef struct msgbox_data_s {
	struct widget_s *container;
	struct widget_s *txt;
	struct widget_s *btn1;
	struct widget_s *btn2;
	int (*btn1_func)(struct widget_s*);
	int (*btn2_func)(struct widget_s*);
} msgbox_data_t;
#endif

#ifndef _HAVE_LISTROW_DATA_TYPE
#define _HAVE_LISTROW_DATA_TYPE
typedef struct listrow_data_s {
	char** values;
} listrow_data_t;
#endif

#ifndef _HAVE_LISTCOLUMN_TYPE
#define _HAVE_LISTCOLUMN_TYPE
typedef struct list_column_s {
	char* name;
	int width;
} list_column_t;
#endif

#ifndef _HAVE_LIST_DATA_TYPE
#define _HAVE_LIST_DATA_TYPE
typedef struct list_data_s {
	int col_cnt;
	int rows;
	int offset;
	int y;
	int (*click)(struct widget_s *);
	list_column_t *columns;
} list_data_t;
#endif

#ifndef _HAVE_OPTBOX_BTN_TYPE
#define _HAVE_OPTBOX_BTN_TYPE
typedef struct optbox_btn_s {
	struct widget_s *btn;
	int (*func)(struct widget_s*);
	struct optbox_btn_s *next;
} optbox_btn_t;
#endif

#ifndef _HAVE_OPTBOX_DATA_TYPE
#define _HAVE_OPTBOX_DATA_TYPE
typedef struct optbox_data_s {
	struct widget_s *container;
	struct widget_s *txt;
	optbox_btn_t *buttons;
} optbox_data_t;
#endif

#ifndef _HAVE_OPTION_DATA_TYPE
#define _HAVE_OPTION_DATA_TYPE
typedef struct option_data_s {
	char com[100];
} option_data_t;
#endif

#ifndef _HAVE_CHECKBOX_DATA_TYPE
#define _HAVE_CHECKBOX_DATA_TYPE
typedef struct checkbox_data_s {
	uint8_t checked;
} check_data_t;
#endif

#ifndef _HAVE_NUMBOX_DATA_TYPE
#define _HAVE_NUMBOX_DATA_TYPE
typedef struct numbox_data_s {
	int value;
	int min;
	int max;
} numbox_data_t;
#endif

#ifndef _HAVE_CONSOLE_LINE_TYPE
#define _HAVE_CONSOLE_LINE_TYPE
typedef struct console_line_s {
	struct console_line_s *prev;
	struct console_line_s *next;
	char str[256];
} console_line_t;
#endif

#ifndef _HAVE_CONSOLE_DATA_TYPE
#define _HAVE_CONSOLE_DATA_TYPE
typedef struct console_data_s {
	console_line_t *lines;
	char command[256];
	int cchar;
} console_data_t;
#endif

#ifndef _HAVE_SLIDE_DATA_TYPE
#define _HAVE_SLIDE_DATA_TYPE
typedef struct slide_data_s {
	int value;
	int min;
	int max;
	sprite_t *sld;
} slide_data_t;
#endif

#ifndef _HAVE_PBAR_DATA_TYPE
#define _HAVE_PBAR_DATA_TYPE
typedef struct pbar_data_s {
	int max;
	int value;
	int blind;
	colour_t colour;
} pbar_data_t;
#endif

#ifndef _HAVE_WIDGET_DATA_TYPE
#define _HAVE_WIDGET_DATA_TYPE
typedef union widget_data_u {
	console_data_t con;
	numbox_data_t num;
	check_data_t chk;
	pbar_data_t pbr;
	msgbox_data_t msg;
	optbox_data_t opb;
	option_data_t opt;
	slide_data_t sld;
	list_data_t lst;
	listrow_data_t row;
} widget_data_t;
#endif

#ifndef _HAVE_WIDGET_EVENTS_TYPE
#define _HAVE_WIDGET_EVENTS_TYPE
typedef struct widget_events_s {
	int (*mclick)(struct widget_s *w);
	int (*mdown)(struct widget_s *w);
	int (*mup)(struct widget_s *w);
	int (*sdown)(struct widget_s *w);
	int (*sup)(struct widget_s *w);
	int (*mmove)(struct widget_s *w);
	int (*kdown)(struct widget_s *w);
	int (*kup)(struct widget_s *w);
	int (*show)(struct widget_s *w);
	int (*hide)(struct widget_s *w);
} widget_events_t;
#endif

#ifndef _HAVE_WIDGET_STYLE_TYPE
#define _HAVE_WIDGET_STYLE_TYPE
typedef struct widget_style_s {
	int x;
	int y;
	int w;
	int h;
	int visible;
	int visibility_changed;
	sprite_t *bg;
	colour_t color;
	colour_t border;
	int has_border;
	int text_align;
	int font_face;
	int font_size;
	colour_t ttcolor;
	colour_t ttbg;
	int has_ttbg;
	colour_t ttborder;
	int has_ttborder;
	int ttfont_face;
	int ttfont_size;
} widget_style_t;
#endif

#ifndef _HAVE_WIDGET_TYPE
#define _HAVE_WIDGET_TYPE
typedef struct widget_s {
	struct widget_s *prev;
	struct widget_s *next;
	uint32_t type;
	uint32_t id;
	textbuffer_t text;
	int hover;
	textbuffer_t htext;
	struct xml_tag_s *x;
	widget_style_t style;
	widget_data_t *data;
	widget_events_t *events;
	struct widget_s *parent;
	struct widget_s *child;
} widget_t;
#endif

/* defined in ui.c */
int ui_init(void);
widget_t *ui_widget_container(void);
void ui_render(void);
void ui_loader(char* str);
void ui_msg(uint8_t type, char* txt, int (*func)(), ...);
void ui_opt(char* txt, ...);

#endif
